﻿#ifndef ROBOT_H_
#define ROBOT_H_

#include <memory>
#include <aris.hpp>
#include "json.hpp"

namespace robot
{
    class SetMaxToq : public aris::core::CloneObject<SetMaxToq, aris::plan::Plan>
    {
    public:
        auto virtual prepareNrt()->void;
        auto virtual executeRT()->int;
        auto virtual collectNrt()->void;

        virtual ~SetMaxToq();
        explicit SetMaxToq(const std::string &name = "set_max_toq");
    };

    class DogReadJoint :public aris::core::CloneObject<DogReadJoint, aris::plan::Plan>
    {
    public:
        auto virtual prepareNrt()->void;
        auto virtual executeRT()->int;

        virtual ~DogReadJoint();
        explicit DogReadJoint(const std::string &name = "dog_read_joint");
    };

    class DogInitPos :public aris::core::CloneObject<DogInitPos, aris::plan::Plan>
    {
    public:
        auto virtual prepareNrt()->void;
        auto virtual executeRT()->int;

        virtual ~DogInitPos();
        explicit DogInitPos(const std::string& name = "dog_get_init_pos");
    };

    class DogSetWalkMode :public aris::core::CloneObject<DogSetWalkMode, aris::plan::Plan>
    {
    public:
        auto virtual prepareNrt()->void;
        auto virtual executeRT()->int;

        virtual ~DogSetWalkMode();
        explicit DogSetWalkMode(const std::string& name = "dog_set_walk_mode");
    private:
        std::string gait_;
        std::string prepose_;
    };

    class DogMoveJoint :public aris::core::CloneObject<DogMoveJoint, aris::plan::Plan>
    {
    public:
        auto virtual prepareNrt()->void;
        auto virtual executeRT()->int;
        auto virtual collectNrt()->void;

        virtual ~DogMoveJoint();
        explicit DogMoveJoint(const std::string &name = "dog_move_joint");
    private:
        double dir_;
    };
    
    class DogHome :public aris::core::CloneObject<DogHome, aris::plan::Plan>
    {
    public:
        auto virtual prepareNrt()->void;
        auto virtual executeRT()->int;

        virtual ~DogHome();
        explicit DogHome(const std::string &name = "dog_home");
    };

    //class DogSwitchPrePose :public aris::core::CloneObject<DogSwitchPrePose, aris::plan::Plan>
    //{
    //public:
    //    auto virtual prepareNrt()->void;
    //    auto virtual executeRT()->int;

    //    virtual ~DogSwitchPrePose();
    //    explicit DogSwitchPrePose(const std::string& name = "dog_switchpose");
    //private:
    //    std::string prepose_;
    //};

    class DogPrepare :public aris::core::CloneObject<DogPrepare, aris::plan::Plan>
    {
    public:
        auto virtual prepareNrt()->void;
        auto virtual executeRT()->int override;

        virtual ~DogPrepare();
        explicit DogPrepare(const std::string &name = "dog_prepare");
    };



    class DogUpDown :public aris::core::CloneObject<DogUpDown, aris::plan::Plan>
    {
    public:
        auto virtual prepareNrt()->void;
        auto virtual executeRT()->int;

        virtual ~DogUpDown();
        explicit DogUpDown(const std::string& name = "dog_updown");
    private:
        double distance_;
    };

    class DogTaBu :public aris::core::CloneObject<DogTaBu, aris::plan::Plan>
    {
    public:
        auto virtual prepareNrt()->void;
        auto virtual executeRT()->int;

        virtual ~DogTaBu();
        explicit DogTaBu(const std::string &name = "dog_tabu");
    private:
        double step_;
    };

    class DogForward :public aris::core::CloneObject<DogForward, aris::plan::Plan>
    {
    public:
        auto virtual prepareNrt()->void;
        auto virtual executeRT()->int;

        virtual ~DogForward();
        explicit DogForward(const std::string &name = "dog_forward");
    private:
        double step_;
    };

    class DogBack :public aris::core::CloneObject<DogBack, aris::plan::Plan>
    {
    public:
        auto virtual prepareNrt()->void;
        auto virtual executeRT()->int;

        virtual ~DogBack();
        explicit DogBack(const std::string& name = "dog_back");
    private:
        double step_;
    };

    class DogLeft :public aris::core::CloneObject<DogLeft, aris::plan::Plan>
    {
    public:
        auto virtual prepareNrt()->void;
        auto virtual executeRT()->int;

        virtual ~DogLeft();
        explicit DogLeft(const std::string& name = "dog_left");
    private:
        double step_;
    };

    class DogRight :public aris::core::CloneObject<DogRight, aris::plan::Plan>
    {
    public:
        auto virtual prepareNrt()->void;
        auto virtual executeRT()->int;

        virtual ~DogRight();
        explicit DogRight(const std::string& name = "dog_right");
    private:
        double step_;
    };

    class DogTurn :public aris::core::CloneObject<DogTurn, aris::plan::Plan>
    {
    public:
        auto virtual prepareNrt()->void;
        auto virtual executeRT()->int;

        virtual ~DogTurn();
        explicit DogTurn(const std::string& name = "dog_turn");
    private:
        double step_;
        double turn_angle_;
    };

    class DogPitch :public aris::core::CloneObject<DogPitch, aris::plan::Plan>
    {
    public:
        auto virtual prepareNrt()->void;
        auto virtual executeRT()->int;

        virtual ~DogPitch();
        explicit DogPitch(const std::string& name = "dog_pitch");
    private:
        double turn_angle_;
    };


    class DogRoll :public aris::core::CloneObject<DogRoll, aris::plan::Plan>
    {
    public:
        auto virtual prepareNrt()->void;
        auto virtual executeRT()->int;

        virtual ~DogRoll();
        explicit DogRoll(const std::string& name = "dog_roll");
    private:
        double turn_angle_;
    };


    class DogYaw :public aris::core::CloneObject<DogYaw, aris::plan::Plan>
    {
    public:
        auto virtual prepareNrt()->void;
        auto virtual executeRT()->int;

        virtual ~DogYaw();
        explicit DogYaw(const std::string& name = "dog_yaw");
    private:
        double turn_angle_;
    };


    // cpp和adams测试 //
    class DogDynamicTest :public aris::core::CloneObject<DogDynamicTest, aris::plan::Plan> {
    public:
        auto virtual prepareNrt()->void;
        auto virtual executeRT()->int override;
  
        virtual ~DogDynamicTest();
        explicit DogDynamicTest(const std::string& name = "dog_dynamic");

    };


    // 正弦曲线 //
    class MoveJS : public aris::core::CloneObject<MoveJS, aris::plan::Plan>
    {
    public:
        auto virtual prepareNrt()->void;
        auto virtual executeRT()->int;
        auto virtual collectNrt()->void;

        explicit MoveJS(const std::string& name = "MoveJS_plan");

    };
	
    class ClickedForward :public aris::core::CloneObject<ClickedForward, aris::plan::Plan>
    {
    public:
        auto virtual prepareNrt()->void;
        auto virtual executeRT()->int;

        virtual ~ClickedForward();
        explicit ClickedForward(const std::string& name = "clicked_forward");

    };

	class DogGet : public aris::core::CloneObject<DogGet, aris::plan::Plan>
	{
	public:
        auto virtual prepareNrt()->void;
        // auto virtual executeRT()->int;
        auto virtual collectNrt()->void;

        explicit DogGet(const std::string& name = "DogGet_plan");
        // ARIS_DEFINE_BIG_FOUR(DogGet);

	// 如果有参数，需要指定相应的成员变量用来获取和使用参数
	};

	class EStop : public aris::core::CloneObject<EStop, aris::plan::Plan>
	{
	public:
        auto virtual prepareNrt()->void;

        explicit EStop(const std::string& name = "DogEStop_plan");
	};
	
    class Speed
    {
    public:
        double w_per;	//关节速度百分比
        double v_tcp;	//TCP线速度mm/s
        double w_tcp;	//空间旋转速度°/s
        double w_ext;	//外部轴角速度°/s
        double v_ext;	//外部轴线速度mm/s
    };

    class Zone
    {
    public:
        double dis;	//转弯区长度m
        double per;	//转弯区百分比分数表达
    };

    class Load
    {
    public:
        double mass;	//质量
        double cog[3];	//质心在x,y,z三个方向的分量
        double pq[4];	//惯性主轴的方向
        double iner[3];	//三个主轴方向的转动惯量
    };

    auto update_state(aris::server::ControlServer& cs)->void;
    auto createUserDataType(aris::core::Calculator& cal, int num)->void;
    auto createModelQuadruped()->std::unique_ptr<aris::dynamic::Model>;
    auto createControllerQuadruped()->std::unique_ptr<aris::control::Controller>;
    auto createPlanQuadruped()->std::unique_ptr<aris::plan::PlanRoot>;

}

#endif
